package com.shark.teach;

import ch.qos.logback.core.util.TimeUtil;

import javax.print.attribute.standard.RequestingUserName;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


class Ticket//资源类  OOP  对象 = Field + Method
{
    private int number = 50;//票数Field

    //操作（卖票 sale）

     //V1
    /*public synchronized void sale() // Method
    {
        if(number >0 )
        {
            System.out.println(Thread.currentThread().getName()+"\t"+"卖出第："+(number--)+"\t还剩下："+number);
            //暂停毫秒
            //try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); }
        }
    }*/

    //V2
    /*public void sale() // Method
    {
        synchronized (this) //synchronized = 独占锁+非公平锁
        {
            if(number >0 )
            {
                System.out.println(Thread.currentThread().getName()+"\t"+"卖出第："+(number--)+"\t还剩下："+number);
                //暂停毫秒
                //try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); }
            }
        }
    }*/

    //V3  JUC start\
    Lock lock = new ReentrantLock(true); //ReentrantLock = 独占锁+非公平锁默认+公平锁同时具备
    public void sale()
    {
        lock.lock();
        try
        {
            if(number > 0)
            {
                System.out.println(Thread.currentThread().getName()+"\t"+"卖出第："+(number--)+"\t还剩下："+number);
            }
        }finally {
            lock.unlock();
        }
    }

}



/**
 * @auther shark
 * @create 2024-08-02 20:45
 *
 *三个售票员    卖出      50张票
 *如何编写企业级需要的工程化代码？ 多对1 多个线程操作同一个资源类
 *
 *  JUC小口诀
 *
 * 1  高聚低耦前提下，线程    操作（卖票 sale）      资源类
 *
 *
 */
public class SaleTicketDemo
{
    public static void main(String[] args) //入口程序
    {
        Ticket ticket = new Ticket();

        ExecutorService threadPool = Executors.newFixedThreadPool(3);

        try
        {
            for (int i = 1; i <=50 ; i++)
            {
                threadPool.execute(() -> ticket.sale());
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPool.shutdown();
        }


    }

    private static void sale01()
    {
        //Thread(Runnable target, String name) Allocates a new Thread object.

        Ticket ticket = new Ticket();


        /*public interface Runnable {

            public abstract void run();
        }*/

        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        },"A").start();

        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        },"B").start();

        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                ticket.sale();
            }
        },"C").start();


        /*new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                for (int i = 0; i < 50; i++) {
                    ticket.sale();
                }
            }
        }, "A").start();

        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                for (int i = 0; i < 50; i++) {
                    ticket.sale();
                }
            }
        }, "B").start();

        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                for (int i = 0; i < 50; i++) {
                    ticket.sale();
                }
            }
        }, "C").start();*/
    }
}

